package com.cardone.common.util;

import com.cardone.common.dto.*;
import org.apache.commons.lang.math.*;

import java.math.*;

/**
 * 分页工具类
 *
 * @author yaohaitao
 */
public class PaginationUtils {
    /**
     * 修正开始行数
     */
    private static int fixBeginRowNum = -1;

    /**
     * 分页行数大小
     */
    private static int size = 10;

    /**
     * 显示代码数量范围
     */
    private static int viewNoNum = 6;

    private PaginationUtils() {
    }

    /**
     * 获取：分页行数大小
     *
     * @return 分页行数大小
     */
    public static int getSize() {
        return PaginationUtils.size;
    }

    /**
     * 设置：分页行数大小
     *
     * @param size 分页行数大小
     */
    public static void setSize(final int size) {
        PaginationUtils.size = size;
    }

    /**
     * 获取：显示代码数量范围
     *
     * @return 显示代码数量范围
     */
    public static int getViewNoNum() {
        return PaginationUtils.viewNoNum;
    }

    /**
     * 设置：显示代码数量范围
     *
     * @param viewNoNum 显示代码数量范围
     */
    public static void setViewNoNum(final int viewNoNum) {
        PaginationUtils.viewNoNum = viewNoNum;
    }

    /**
     * 实例化：分页
     *
     * @param no        页面代码
     * @param size      分页行数大小
     * @param totalSize 总数量
     * @return 分页
     */
    public static <T> PaginationDto<T> newPagination(final int no, final int size, final long totalSize) {
        return PaginationUtils.newPagination(no, size, 0, totalSize);
    }

    /**
     * 实例化：分页
     *
     * @param no        页面代码
     * @param size      分页行数大小
     * @param viewNoNum 显示代码数量范围
     * @param totalSize 总数量
     * @return 分页
     */
    public static <T> PaginationDto<T> newPagination(final int no, final int size, final int viewNoNum, final long totalSize) {
        final PaginationDto<T> pagination = new PaginationDto<T>();

        if (totalSize < 1) {
            return pagination;
        }

        pagination.setTotalSize(totalSize);

        if (size < 1) {
            pagination.setSize(PaginationUtils.size);
        } else {
            pagination.setSize(Math.max(size, PaginationUtils.size));
        }

        // 向上取整: 1.01 = 2
        final int totalNo = new java.math.BigDecimal(totalSize).divide(new BigDecimal(pagination.getSize()), BigDecimal.ROUND_UP).toBigInteger().intValue();

        pagination.setTotalNo(totalNo);

        pagination.setNo(Math.min(Math.max(no, 1), totalNo));

        pagination.setHasFirstNo(pagination.getNo() >= 1);

        pagination.setPreviousNo(Math.max(pagination.getNo() - 1, 1));

        pagination.setHasPreviousNo(pagination.isHasFirstNo());

        pagination.setNextNo(Math.min(pagination.getNo() + 1, totalNo));

        pagination.setHasNextNo(pagination.getNo() < pagination.getTotalNo());

        pagination.setLastNo(totalNo);

        pagination.setHasLastNo(pagination.isHasNextNo());

        pagination.setEndRowNum(pagination.getNo() * pagination.getSize());

        pagination.setBeginRowNum(pagination.getEndRowNum() - (pagination.getSize() + PaginationUtils.fixBeginRowNum));

        if (viewNoNum < 1) {
            return pagination;
        }

        final int newViewNoNum = Math.max(viewNoNum, PaginationUtils.viewNoNum);

        final int viewNoNumHalf = new java.math.BigDecimal(newViewNoNum).divide(new BigDecimal(2), BigDecimal.ROUND_HALF_UP).toBigInteger().intValue();

        int startNo = Math.max(pagination.getNo() - viewNoNumHalf, 1);

        final int endNo = Math.min((startNo + newViewNoNum) - 1, totalNo);

        if (((endNo - startNo) + 1) < newViewNoNum) {
            startNo = Math.max((endNo - newViewNoNum) + 1, 1);
        }

        final int[] nos = new IntRange(startNo, endNo).toArray();

        pagination.setNos(nos);

        return pagination;
    }

    /**
     * 实例化：分页
     *
     * @param no        页面代码
     * @param totalSize 总数量
     * @return 分页
     */
    public static <T> PaginationDto<T> newPagination(final int no, final long totalSize) {
        return PaginationUtils.newPagination(no, PaginationUtils.size, 0, totalSize);
    }

    /**
     * 设置：修正开始行数
     *
     * @param fixBeginRowNum 修正开始行数
     */
    public static void setFixBeginRowNum(final int fixBeginRowNum) {
        PaginationUtils.fixBeginRowNum = fixBeginRowNum;
    }
}